<?php 

class ContentHtml extends DOMDocument
{
  public $url;
  
  public function __construct($url, $content, $version, $encoding = NULL)
  {
    parent::__construct($version, $encoding);

    $this->url = $url;
    
    @$this->loadHTML($content);
  }
  /**
   * Method to return url
   */
  public function getUrl()
  {
    return $this->url;
  }
  /**
   * Method to get domain from url
   * 
   * @param string $url
   */
  public function getDomain($url = null)
  {
    $parsed_url = parse_url(urldecode($url));
    
    if(is_array($parsed_url) && count($parsed_url))
    {
      if(isset($parsed_url["host"]))
      {
        return $parsed_url["host"];
      }
    }
    return null;
  }
  /**
   * Make unique link format
   * @param string $parent
   * @param string $link
   */
  public function doNormalizeLink($parent, $link)
  {
    $parsed_parent  = parse_url(urldecode($parent));
    $parsed_link    = parse_url(urldecode($link));
    
    if(! $parsed_parent || ! $parsed_link)
    {
      return null;
    }
    
    $parent_keys_to_remove = array(
      "user"      => "", 
      "pass"      => "", 
      "path"      => "", 
      "query"     => "", 
      "fragment"  => ""
    );
    
    $parsed_parent = array_diff_key($parsed_parent, $parent_keys_to_remove);
    
    $link_keys_to_remove = array(
      "user"      => "", 
      "pass"      => "", 
      "fragment"  => ""
    );
    
    $parsed_link = array_diff_key($parsed_link, $link_keys_to_remove);
    
    if(! $parsed_parent || ! $parsed_link)
    {
      return null;
    }
    
    return urldecode(http_build_url(array_merge($parsed_parent, $parsed_link)));
  }
  /**
   * Check is link is inner
   * @param string $parent
   * @param string $link
   */
  public function isInnerLink($parent, $link)
  {
    $parsed_parent  = parse_url($parent);
    $parsed_link    = parse_url($link);
    
    if(! isset($parsed_link["host"]))
    {
      return true;
    }
    
    if($parsed_parent["host"] == $parsed_link["host"])
    {
      if(isset($parsed_parent["scheme"]) && isset($parsed_link["scheme"]))
      {
        if($parsed_parent["scheme"] == $parsed_link["scheme"])
        {
          return true;
        }
      }
    }
    return false;
  }
  /**
   * Method to get all links from DOM
   * 
   * @param string $url
   */
  public function getLinksFromDom ()
  {
    $xpath = new DOMXPath($this);
    
    return $xpath->evaluate("//a"); 
  }
  /**
   * Method to get inner links
   * @param $url
   */
  public function getInnerLinks()
  {
    $hrefs = $this->getLinksFromDom();
    
    $links = array();
    
    for($i = 0; $i < $hrefs->length; $i ++)
    {
      $href = $hrefs->item($i);
      // Get link text and normalize link
      $link = $this->doNormalizeLink($this->url, $href->getAttribute('href'));
      
      if(! $this->isInnerLink($this->url, $link))
      {
        continue;
      }
      
      $links[] = $link;
    }
    return $links;
  }
  
  /**
   * Method to get outer links
   * @param $url
   */
  public function getOuterLinks()
  {
    $hrefs = $this->getLinksFromDom();
    $links = array();
    
    for($i = 0; $i < $hrefs->length; $i ++)
    {
      $href = $hrefs->item($i);
      // Get link text and normalize link
      $link = $this->doNormalizeLink($this->url, $href->getAttribute('href'));
      
      if($this->isInnerLink($this->url, $link))
      {
        continue;
      }
      
      $links[] = $link;
    }
    return $links;
  }
  /**
   * Method to get page title
   */
  public function getTitle()
  {
    $xpath = new DOMXPath($this);
    
    $item = $xpath->evaluate("//title")->item(0);
    
    if(is_object($item))
    {
      return $item->textContent;
    }
    
    return time();
  }
  /**
   * Return encoding from html
   */
  public function getEncoding()
  {
    $xpath = new DOMXPath($this);
    
    $items = $xpath->evaluate("//meta");
    
    foreach ($items as $item)
    {
      if($item->getAttribute('http-equiv') == "Content-Type")
      {
        $varname      = " charset=";
        $content_type = $item->getAttribute('content');
        
        $varposition = mb_strpos($content_type, $varname);
        
        if ($varposition)
        {
          $varposition += mb_strlen($varname);
                
          return mb_substr($content_type, $varposition);
        }
      }      
    }
    
    return NULL;
  }
}
